package pailaidai.hc.com.mysvgdemo.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

/**
 * Created by Administrator on 2018/4/4.
 */

public class ScrollLayout extends ViewGroup {
    private static final String TAG="ScrollLayout";
    private Scroller mScroller;
    private VelocityTracker mVelocityTracker;
    private int mCurScreen;
    private int mDefaultScreen=0;
    private static final int TOUCH_STATE_REST=0;
    private static final int TOUCH_STATE_SCROLLING=1;
    private static final int SNAP_VELOCITY=600;
    private int mTouchState=TOUCH_STATE_REST;
    private int mTouchSlop;
    private float mLastMotionX;
    private float mLastMotionY;
    public ScrollLayout(Context context) {
        super(context);
    }

    public ScrollLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller=new Scroller(context);
        mCurScreen=mDefaultScreen;
        mTouchSlop= ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
        if(b){
            int childLeft=0;
            final int childCount=getChildCount();
            for(int a = 0; a<childCount; a++){
                final View childView=getChildAt(i);
                if(childView.getVisibility()!=View.GONE){
                    final int childWidth=childView.getMeasuredWidth();
                    childView.layout(childLeft,0,childLeft+childWidth,childView.getMeasuredHeight());
                    childLeft+=childWidth;
                }
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width=MeasureSpec.getSize(widthMeasureSpec);
        final int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        if(widthMode!=MeasureSpec.EXACTLY){
            throw new IllegalStateException("ScrollLayout only canmCurScreen run at EXACTLY mode!");
        }
      final int heightMode=MeasureSpec.getMode(heightMeasureSpec);
        if(heightMode!=MeasureSpec.EXACTLY){
            throw new IllegalStateException("ScrollLayout only can run at EXACTLY mode!");
        }
        final int count=getChildCount();
        for(int i=0;i<count;i++){
            getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
        }
       scrollTo(mCurScreen*width,0);
    }
      public void snapToDestination(){
          final int screenWidth=getWidth();
          final int destScreen=(getScrollX()+screenWidth/2)/screenWidth;
          snapToScreen(destScreen);
      }

    private void snapToScreen(int destScreen) {
        destScreen=Math.max(0,Math.min(destScreen,getChildCount()-1));
        if(getScaleX()!=(destScreen*getWidth())){
            final int delts= (int) (destScreen*getWidth()-getScaleX());
            mScroller.startScroll(getScrollX(),0,delts,0,Math.abs(delts)*2);
            mCurScreen=destScreen;
            invalidate();
        }
    }
    public void setToScreen(int whichScreen){
        whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-1));
        mCurScreen=whichScreen;
        scrollTo(whichScreen*getWidth(),0);
    }
   public int getCurScreen(){
       return mCurScreen;
   }

    @Override
    public void computeScroll() {
        if(mScroller.computeScrollOffset()){
            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
             postInvalidate();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(mVelocityTracker==null){
            mVelocityTracker=VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
        final  int action=event.getAction();
        final float x=event.getX();
        final float y=event.getY();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                if(!mScroller.isFinished()){
                    mScroller.abortAnimation();
                }
                mLastMotionX=x;
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaX= (int) (mLastMotionX-x);
                mLastMotionX=x;
                scrollBy(deltaX,0);
                break;
            case MotionEvent.ACTION_UP:
                final VelocityTracker velocityTracker=mVelocityTracker;
                velocityTracker.computeCurrentVelocity(1000);
                int velocityX= (int) velocityTracker.getXVelocity();
                if(velocityX>SNAP_VELOCITY&&mCurScreen>0){
                    snapToScreen(mCurScreen-1);
                }else if(velocityX<-SNAP_VELOCITY&&mCurScreen<getChildCount()-1){
                    snapToScreen(mCurScreen+1);
                }else {
                    snapToDestination();
                }
                if(mVelocityTracker!=null){
                    mVelocityTracker.recycle();
                    mVelocityTracker=null;
                }
                mTouchState=TOUCH_STATE_REST;
                break;
            case MotionEvent.ACTION_CANCEL:
                mTouchState=TOUCH_STATE_REST;
                break;
        }
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action=ev.getAction();
        if((action==MotionEvent.ACTION_MOVE)&&(mTouchState!=TOUCH_STATE_REST)){
            return true;
        }
        final float x=ev.getX();
        final float y=ev.getY();
        switch (action){
            case MotionEvent.ACTION_MOVE:
                final  int xDiff= (int) Math.abs(mLastMotionX-x);
                if(xDiff>mTouchSlop){
                    mTouchState=TOUCH_STATE_SCROLLING;
                }
                break;
            case MotionEvent.ACTION_DOWN:
                  mLastMotionX=x;
                  mLastMotionY=y;
                mTouchState=mScroller.isFinished()?TOUCH_STATE_REST:TOUCH_STATE_SCROLLING;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                  mTouchState=TOUCH_STATE_REST;
                break;
        }

        return mTouchState!=TOUCH_STATE_REST;
    }
}
